package org.syncsoft.overalt.domain.document.joson;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.syncsoft.overalt.common.json.AbstractJsonConverter;
import org.syncsoft.overalt.common.json.JSonTree;
import org.syncsoft.overalt.domain.community.entity.Community;
import org.syncsoft.overalt.domain.document.entity.Document;
import org.syncsoft.overalt.domain.document.entity.Policy;
import org.syncsoft.overalt.domain.tag.entity.Tag;
import org.syncsoft.overalt.domain.user.entity.User;

/**
 * 
 * @author tptfc
 *
 */
public abstract class AbstractDocumentJsonConverter<T> extends AbstractJsonConverter<T> {
	
	/**
	 * 
	 * @param jsonTree
	 * @param document
	 * @param documentEntity
	 * @return
	 */
	protected Document extractDocument(JSonTree jsonTree, JSonTree documentEntity) {
		Document document = null;
		if (documentEntity != null) {
			document = new Document();
			populeEntity(document, documentEntity);
			document.setCode(Integer.parseInt(documentEntity.getParameterValue("code")));
			document.setTitle(documentEntity.getParameterValue("title"));
			document.setDescription(documentEntity.getParameterValue("description"));
			
			extractPath(documentEntity, document);
			
			User user = extractUser(jsonTree);
			document.setUser(user);
			
			Policy policy = extractPolicy(documentEntity);
			document.setPolicy(policy);
			
			Set<Community> communities = extractCommunities(documentEntity);
			document.setCommunities(communities);
			
			Set<Tag> tags = extractTags(jsonTree);
			document.setTags(tags);
		}
		return document;
	}

	/**
	 * 
	 * @param entity
	 * @return
	 */
	private Set<Community> extractCommunities(JSonTree entity) {
		Set<Community> communities = new HashSet<Community>();
		Collection<JSonTree> communitiesEntiey = entity.getJsonTreesFronEntityName("community");
		
		if (communitiesEntiey != null) {
			for (JSonTree communityEntity: communitiesEntiey) {
				Community community = new Community();
				community.setCode(Integer.parseInt(communityEntity.getParameterValue("code")));
				community.setName(communityEntity.getParameterValue("name"));
				communities.add(community);
			}
		}
		
		return communities;
	}
	
	/**
	 * 
	 * @param documentEntity
	 * @return
	 */
	private Policy extractPolicy(JSonTree documentEntity) {
		Policy policy = null;
		JSonTree policyEntity = documentEntity.getJsonTreeFronEntityName("policy");
		if (policyEntity != null) {
			String stringCode = policyEntity.getParameterValue("code");
			if (stringCode != null) {
				policy = new Policy();
				try {
					policy.setCode(Integer.parseInt(stringCode));
				} catch (NumberFormatException e) {
					policy = null;
				}
			}
		}
		return policy;
	}

	/**
	 * 
	 * @param documentEntity
	 * @param document
	 */
	private void extractPath(JSonTree documentEntity, Document document) {
		String path = documentEntity.getParameterValue("path");
		
		if (path != null) {
			int beginIndex = path.lastIndexOf("/");
			
			if (beginIndex > -1) {
				path = path.substring(beginIndex +1);
				document.setFileName(path);
			}
		}
	}

	/**
	 * @precondition jsonTree != null
	 * @postcondition returned null if not found user in jsonTree
	 * 
	 * @param jsonTree
	 * @return user
	 */
	protected User extractUser(JSonTree jsonTree) {
		User user = null;
		
		if (jsonTree != null) {
			JSonTree userEntity = jsonTree.getJsonTreeFronEntityName("owner");
			if (userEntity != null) {
				user = new User();
				populeEntity(user,  userEntity);
			}
		}
		
		return user;
	}

	/**
	 * @precondition jsonTree != null
	 * @postcondition returned a empty Set if not found user in jsonTree
	 * @param jsonTree
	 * @return
	 */
	private Set<Tag> extractTags(JSonTree jsonTree) {
		Collection<JSonTree> tagsEntities = jsonTree.getJsonTreesFronEntityName("tags");
		Set<Tag> tags = new HashSet<Tag>();
		
		for (JSonTree tagEntity : tagsEntities) {
			Tag tag = new Tag();
			populeEntity(tag, tagEntity);
			tags.add(tag);
		}
		return tags;
	}
}
